﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Billing.CashDesk.CashDeskService;
using Billing.WindowsBase;

namespace Billing.CashDesk
{
    [ToolboxItem(true)]
    public partial class PaymentControl : Billing.WindowsBase.CustomControls.BaseControl
    {
        Control controlToActivate;

        PaymentObject paymentObject = null;

        public PaymentControl()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            btClear_Click(btClear, EventArgs.Empty);

            controlToActivate = valPhone;
        }

        private void btClear_Click(object sender, EventArgs e)
        {
            OnBeforeOperation(Operation.Cancel);

            valIdentNum.Text = string.Empty;
            valPhone.Text = string.Empty;
            paymentObject = new PaymentObject();
            paymentObject.ClientInfo = new ClientInfo();
            paymentObject.ClientInfo.PaymentItems = new PaymentItem[0];
            clientInfoBindingSource.DataSource = paymentObject.ClientInfo;
            billItemBindingSource.DataSource = paymentObject.ClientInfo.PaymentItems;

            valPrintDetails.CheckState = CheckState.Checked;
            valInMoney.Value = 0M;
            valPaidMoney.Value = 0;
            lbBackMoney.Text = (0M).ToString("0.00");
            ActivateControl(valPhone);
            OnBeforeOperation(Operation.Search);
        }

        private void btSearch_Click(object sender, EventArgs e)
        {
            try
            {
                ICashDeskService service = ServiceFactory.CreateCashDeskService();

                paymentObject = new PaymentObject();

                if (string.IsNullOrEmpty(valIdentNum.Text))
                {
                    if (string.IsNullOrEmpty(valPhone.Text))
                    {
                        ShowWarning("ძებნის პარამეტრები არ არის შევსებული");
                        return;
                    }
                    else
                    {
                        paymentObject.SearchType = SearchType.ByPhoneNumber;
                        paymentObject.SearchKey = valPhone.Text;
                        controlToActivate = valPhone;
                    }
                }
                else
                {
                    paymentObject.SearchKey = valIdentNum.Text;
                    paymentObject.SearchType = SearchType.ByIdentificationNumber;
                    controlToActivate = valIdentNum;
                }

                ClientInfo[] cc = service.GetClientInfo(ref paymentObject);

                if (cc.Length > 1)
                {
                    using (ChooseClientForm f = new ChooseClientForm())
                    {
                        f.Initialize(new List<ClientInfo>(cc));
                        DialogResult dr = f.ShowDialog(this);

                        if (dr == DialogResult.OK)
                        {
                            paymentObject.ClientInfo = f.SelectedDataObject;
                        }
                        else
                        {
                            btClear_Click(btClear, EventArgs.Empty);
                            return;
                        }
                    }
                }
                else if (cc.Length == 0)
                {
                    ShowWarning("კლიენტი ვერ მოიძებნა");
                    ActivateControl();
                    return;
                }
                else
                {
                    paymentObject.ClientInfo = cc[0];
                }

                clientInfoBindingSource.DataSource = paymentObject.ClientInfo;

                service.GetBillInfo(ref paymentObject);
                decimal money = 0;
                foreach (PaymentItem itm in paymentObject.ClientInfo.PaymentItems)
                {
                    money += itm.BillMoney;
                }


                billItemBindingSource.DataSource = paymentObject.ClientInfo.PaymentItems;

                valInMoney.Value = GetEstimatedPaidMoney(money >= 0 ? 0 : money * -1);
                valPaidMoney.Value = valInMoney.Value;

                lbBackMoney.Text = (0M).ToString("0.00");
                grdPaymentItems.DataBind();

                ActivateControl(valInMoney);
                OnBeforeOperation(Operation.Print);
            }
            catch (Exception x)
            {
                ShowError(x);
            }
        }

        private decimal GetEstimatedPaidMoney(decimal paidMoney)
        {
            int charge = Convert.ToInt32(paidMoney * 100);

            int module = charge % 100;

            return Convert.ToDecimal((charge + 100 - module) / 100M);
        }

        private void ActivateControl(Control controlToActivate)
        {
            this.controlToActivate = controlToActivate;
            ActivateControl();
        }

        private void ActivateControl()
        {
            if (controlToActivate == null)
            {
                controlToActivate = valPhone;
            }
            controlToActivate.Select();
            if (controlToActivate is TextBoxBase)
                (controlToActivate as TextBoxBase).SelectAll();

            if (controlToActivate is Infragistics.Win.UltraWinEditors.UltraWinEditorMaskedControlBase)
                (controlToActivate as Infragistics.Win.UltraWinEditors.UltraWinEditorMaskedControlBase).SelectAll();
        }

        private void valInMonay_KeyUp(object sender, KeyEventArgs e)
        {

        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Enter)
            {
                if (valPhone.Focused || valIdentNum.Focused)
                {
                    btSearch_Click(btSearch, EventArgs.Empty);
                }
                else if (valInMoney.Focused)
                {
                    ActivateControl(valPaidMoney);
                }
                else if (valPaidMoney.Focused)
                {
                    if (paymentObject.PaymentOrderID > 0)
                    {
                        OnBeforeOperation(Operation.Pay);
                        btPay_Click(btPay, EventArgs.Empty);
                    }
                    else
                    {
                        OnBeforeOperation(Operation.Print);
                        btPrint_Click(btPrint, EventArgs.Empty);
                    }
                }
            }
            if (keyData == Keys.Escape)
            {
                if (valPhone.Focused)
                {
                    btClear_Click(btClear, EventArgs.Empty);
                }
                else if (valIdentNum.Focused)
                {
                    ActivateControl(valPhone);
                }
                else if (valInMoney.Focused)
                {
                    ActivateControl(valIdentNum);
                }
                else if (valPaidMoney.Focused)
                {
                    ActivateControl(valInMoney);
                }
                else
                {
                    ActivateControl(valPaidMoney);
                }
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void btPay_Click(object sender, EventArgs e)
        {
            try
            {
                if (paymentObject.ClientInfo.PaymentItems == null || paymentObject.ClientInfo.PaymentItems.Length == 0)
                {
                    ShowWarning("გადასახდელი არაფერია");
                    return;
                }

                if (paymentObject.ClientInfo.PaymentItems[0].PaidMoney == 0)
                {
                    ShowWarning("კლიენტს თანხა არ შემოუტანია");
                    return;
                }

                if (paymentObject.PaymentOrderID == 0)
                {
                    ShowWarning("გადახდის ბრძანება არ არის დაბეჭდილი!");
                }

                if (ShowQuestion("დარწმუნებული ხართ რომ გსურთ გადახდა?") == DialogResult.Yes)
                {
                    ICashDeskService service = ServiceFactory.CreateCashDeskService();

                    service.Pay(paymentObject);

                    ShowInformation("ოპერაცია დამთავრდა წარმატებით");
                    btClear_Click(btClear, EventArgs.Empty);
                }
            }
            catch (Exception x)
            {
                ShowError(x);
            }
        }

        private void btPrint_Click(object sender, EventArgs e)
        {
            try
            {
                if (paymentObject.ClientInfo.PaymentItems == null || paymentObject.ClientInfo.PaymentItems.Length == 0)
                {
                    ShowWarning("გადასახდელი არაფერია");
                    return;
                }

                if (paymentObject.ClientInfo.PaymentItems[0].PaidMoney == 0)
                {
                    ShowWarning("კლიენტს თანხა არ შემოუტანია");
                    return;
                }

                if (ShowQuestion("დარწმუნებული ხართ რომ გსურთ გადახდის ბრძანების დაბეჭდვა?") == DialogResult.Yes)
                {
                    ICashDeskService service = ServiceFactory.CreateCashDeskService();

                    List<PrintDoc> printdocs = new List<PrintDoc>(2);
                    PrintDoc p1 = new PrintDoc();
                    p1.Name = "გადახდის ბრძანება";
                    p1.Path = "/BillingReports/CashDeskPaymentOrder";

                    long? paymentOrderId = service.CreatePaymentOrder(paymentObject);

                    if (paymentOrderId == null)
                    {
                        throw new BillingApplicationException("შეუძლებელია გადახდის ბრძანების შექმნა");
                    }

                    paymentObject.PaymentOrderID = paymentOrderId.Value;
                    p1.PaymentObject = paymentObject;

                    p1.ReporParameteres.Add(new Microsoft.Reporting.WinForms.ReportParameter("paymentOrderID", paymentObject.PaymentOrderID.ToString()));
                    printdocs.Add(p1);

                    if (valPrintDetails.CheckState == CheckState.Checked)
                    {
                        PrintDoc p2 = new PrintDoc();
                        p2.Name = "დეტალური ამონაბეჭდი";
                        p2.Path = "/BillingReports/CashDeskLastDetails";
                        p2.PaymentObject = paymentObject;
                        p2.ReporParameteres.Add(new Microsoft.Reporting.WinForms.ReportParameter("clientID", paymentObject.ClientInfo.ID.ToString()));
                        p2.ReporParameteres.Add(new Microsoft.Reporting.WinForms.ReportParameter("accountNumber", paymentObject.SearchKey));
                        printdocs.Add(p2);
                    }

                    billItemBindingSource.DataSource = paymentObject.ClientInfo.PaymentItems;
                    if (paymentObject.PaymentOrderID > 0)
                    {
                        using (PrintForm f = new PrintForm(printdocs))
                        {
                            f.PrepareForSelectDialogStyle();
                            DialogResult dr = f.ShowDialog(this);
                            if (dr != DialogResult.Cancel)
                            {
                                OnBeforeOperation(Operation.Pay);
                            }
                            else
                            {
                                paymentObject.PaymentOrderID = 0;
                                OnBeforeOperation(Operation.Print);
                                btPrintAgain_Click(btPrintAgain, EventArgs.Empty);
                            }
                        }
                        ActivateControl(valPaidMoney);
                    }
                }
            }
            catch (Exception x)
            {
                ShowError(x);
            }
        }

        private void OnBeforeOperation(Operation operation)
        {
            switch (operation)
            {
                case Operation.Search:
                    valPhone.ReadOnly = false;
                    valIdentNum.ReadOnly = valPhone.ReadOnly;
                    btClear.Enabled = !valPhone.ReadOnly;
                    btSearch.Enabled = !valPhone.ReadOnly;

                    valInMoney.ReadOnly = true;
                    valPaidMoney.ReadOnly = valInMoney.ReadOnly;

                    gbxActions.Enabled = false;

                    btPrint.Show();
                    btPrintAgain.Hide();
                    break;
                case Operation.AdditionalInfo:
                    valPhone.ReadOnly = false;
                    valIdentNum.ReadOnly = valPhone.ReadOnly;
                    btClear.Enabled = !valPhone.ReadOnly;
                    btSearch.Enabled = !valPhone.ReadOnly;

                    valInMoney.ReadOnly = false;
                    valPaidMoney.ReadOnly = valInMoney.ReadOnly;

                    gbxActions.Enabled = false;

                    btPrint.Enabled = false;
                    btPrintAgain.Enabled = false;
                    btPay.Enabled = false;

                    btPrint.Show();
                    btPrintAgain.Hide();
                    break;
                case Operation.Print:
                    valPhone.ReadOnly = false;
                    valIdentNum.ReadOnly = valPhone.ReadOnly;
                    btClear.Enabled = !valPhone.ReadOnly;
                    btSearch.Enabled = !valPhone.ReadOnly;

                    valInMoney.ReadOnly = false;
                    valPaidMoney.ReadOnly = valInMoney.ReadOnly;

                    gbxActions.Enabled = true;

                    btPrint.Enabled = true;
                    btPrintAgain.Enabled = false;
                    btPay.Enabled = false;

                    btPrint.Show();
                    btPrintAgain.Hide();
                    break;
                case Operation.Pay:
                    valPhone.ReadOnly = true;
                    valIdentNum.ReadOnly = valPhone.ReadOnly;
                    btClear.Enabled = !valPhone.ReadOnly;
                    btSearch.Enabled = !valPhone.ReadOnly;

                    valInMoney.ReadOnly = true;
                    valPaidMoney.ReadOnly = valInMoney.ReadOnly;

                    gbxActions.Enabled = true;

                    btPrint.Enabled = false;
                    btPrintAgain.Enabled = true;
                    btPay.Enabled = true;

                    btPrint.Hide();
                    btPrintAgain.Show();

                    break;
                default:
                    //Cancel && Done
                    valPhone.ReadOnly = false;
                    valIdentNum.ReadOnly = valPhone.ReadOnly;
                    btClear.Enabled = !valPhone.ReadOnly;
                    btSearch.Enabled = !valPhone.ReadOnly;

                    valInMoney.ReadOnly = false;
                    valPaidMoney.ReadOnly = valInMoney.Enabled;

                    gbxActions.Enabled = false;

                    btPrint.Enabled = false;
                    btPrintAgain.Enabled = false;
                    btPay.Enabled = false;

                    btPrint.Hide();
                    btPrintAgain.Show();
                    break;
            }
        }

        public enum Operation
        {
            Search,
            AdditionalInfo,
            Print,
            Pay,
            Cancel,
            Done
        }

        private void btPrintAgain_Click(object sender, EventArgs e)
        {
            OnBeforeOperation(Operation.Print);
        }

        private void btViewDetails_Click(object sender, EventArgs e)
        {
            List<PrintDoc> printdocs = new List<PrintDoc>(1);

            if (valPrintDetails.CheckState == CheckState.Checked)
            {
                PrintDoc p2 = new PrintDoc();
                p2.Name = "დეტალური ამონაბეჭდი";
                p2.Path = "/BillingReports/CashDeskLastDetails";
                p2.PaymentObject = paymentObject;
                p2.ReporParameteres.Add(new Microsoft.Reporting.WinForms.ReportParameter("clientID", paymentObject.ClientInfo.ID.ToString()));
                p2.ReporParameteres.Add(new Microsoft.Reporting.WinForms.ReportParameter("accountNumber", paymentObject.SearchKey));
                printdocs.Add(p2);
            }

            using (PrintForm f = new PrintForm(printdocs))
            {
                DialogResult dr = f.ShowDialog(this);
            }
        }

        private void btViewStatement_Click(object sender, EventArgs e)
        {
            List<PrintDoc> printdocs = new List<PrintDoc>(1);

            if (valPrintDetails.CheckState == CheckState.Checked)
            {
                PrintDoc p2 = new PrintDoc();
                p2.Name = "ამონაწერი";
                p2.Path = "/BillingReports/PaymentAnalyses/StatementSelectByPeriod";
                p2.PaymentObject = paymentObject;
                p2.ReporParameteres.Add(new Microsoft.Reporting.WinForms.ReportParameter("ClientID", paymentObject.ClientInfo.ID.ToString()));
                p2.ReporParameteres.Add(new Microsoft.Reporting.WinForms.ReportParameter("DateFrom", DateTime.Today.AddDays(-DateTime.Today.Day + 1).AddMonths(-1).ToShortDateString()));
                p2.ReporParameteres.Add(new Microsoft.Reporting.WinForms.ReportParameter("DateTo", DateTime.Today.ToShortDateString()));
                printdocs.Add(p2);
            }

            using (PrintForm f = new PrintForm(printdocs))
            {
                DialogResult dr = f.ShowDialog(this);
            }
        }

        private void valInMoney_ValueChanged(object sender, EventArgs e)
        {
            bool update = valInMoney.Value < valPaidMoney.Value;

            valPaidMoney.MaxValue = valInMoney.Value;
            if (update)
                valPaidMoney.Value = valInMoney.Value;
            if (valInMoney.ReadOnly || valPaidMoney.ReadOnly) return;
            decimal bm = valInMoney.Value - valPaidMoney.Value;

            lbBackMoney.Text = (bm >= 0) ? bm.ToString("### ##0.00") : (0M).ToString("0.00");
            OnBeforeOperation(Operation.Print);
        }

        private void valInMoney_Enter(object sender, EventArgs e)
        {
            valInMoney.SelectAll();
        }

        private void valPaidMoney_Enter(object sender, EventArgs e)
        {
            valPaidMoney.SelectAll();
        }
    }
}
